package ee.objectCloner.impl.cloners;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import ee.objectCloner.CustomCloner;
import ee.objectCloner.ObjectCloner;

public class HashSetCloner implements CustomCloner {

	@Override
	public Object clone(Object source, ObjectCloner objectCloner) {

		Set<?> sourceSet = (Set<?>) source;
		Set<Object> destination = new HashSet<Object>(sourceSet.size());

		for (Object o : sourceSet) {
			destination.add(objectCloner.clone(o));
		}

		return destination;
	}

	/**
	 * A Set has no way to set or get specific elements. This method removes all entries of the destination 
	 * and clones the objects in source.
	 */
	@Override
	public void copy(Object source, Object destination,
			ObjectCloner objectCloner) {
		if (source.equals(destination)) {
			return;
		}

		Set<?> sourceSet = (Set<?>) source;
		
		@SuppressWarnings("unchecked")
		Set<Object> destinationSet = (Set<Object>) destination;
		destinationSet.removeAll(destinationSet);
		
		for (Object o : sourceSet) {
			destinationSet.add(objectCloner.clone(o));
		}
	}

	@Override
	public boolean canClone(Class<?> type) {
		return type.equals(Map.class) || type.equals(HashMap.class);
	}

	@Override
	public boolean canCopy(Class<?> sourceType, Class<?> destinationType) {
		return Map.class.isAssignableFrom(sourceType) && Map.class.isAssignableFrom(destinationType);
	}
}
